from not_so_free_marker import statics
from not_so_free_marker.enums import MarkTypeEnum
from not_so_free_marker.models import RegMatch


# 从模板中去掉注释.
# 基本原理: 查找<#--和-->,并去掉中间的部分.
# 体现了这个软件的基本操作:先用正则找到待处理区的开头和结尾,然后根据规则替换.
#
# 如果只支持一行的注释,不用这么麻烦,用正则查找<#--XXXX-->然后删除就可以了.
def process(template_str: str):
    comment_tags = get_tags(template_str)
    if len(comment_tags) < 1:
        return template_str

    processed_array = []  # 合并之后的文本列表.模拟StringBuilder的机制,入队列,输出的时候join
    end_index = 0  # 游标.上一个匹配项的结尾.对于刚开始,上一个匹配的结尾就是整个模板的开头,也就是0
    in_comment_area = False  # 当前游标是否在注释区域中,如果在才认为遇到的-->标记是结束,否则忽视.这是提高兼容性.防止模板中本来就有的-->标记造成干扰(比如html的注释结束符号也是-->)

    # 主循环,基本逻辑:根据查找到注释的开头和结尾,重新拼接一下整个模板,拼接的时候,跳过注释的内容部分.
    for m in comment_tags:
        if m.type == MarkTypeEnum.REG_COMMENT_HEAD:
            processed_array.append(template_str[end_index:m.position].lstrip("\n"))
            in_comment_area = True
        elif in_comment_area and m.type == MarkTypeEnum.REG_COMMENT_TAIL:
            end_index = m.position_end
            in_comment_area = False

    processed_array.append(template_str[end_index:].lstrip("\n"))  # 粘贴最后一个匹配至模板的结尾.

    return "".join(processed_array)


def get_tags(template_str: str):
    comment_tags = []
    for t in statics.regCommentHead.finditer(template_str):  # 找头
        reg_item = RegMatch()
        reg_item.position = t.start(0)
        reg_item.position_end = t.end(0)
        reg_item.type = MarkTypeEnum.REG_COMMENT_HEAD
        reg_item.tagStr = t.group(0)
        comment_tags.append(reg_item)

    for t in statics.regCommentTail.finditer(template_str):  # 找尾
        reg_item = RegMatch()
        reg_item.position = t.start(0)
        reg_item.position_end = t.end(0)
        reg_item.type = MarkTypeEnum.REG_COMMENT_TAIL
        reg_item.tagStr = t.group(0)
        comment_tags.append(reg_item)

    comment_tags.sort(key=lambda a: a.position)  # 根据位置排序.以便后续能够顺序处理匹配项.
    return comment_tags
